package com.guosen.web.mocker

import com.alibaba.fastjson.JSON
import org.codehaus.groovy.control.CompilerConfiguration
import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.AbstractHandler
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import javax.servlet.ServletException
import javax.servlet.ServletInputStream
import javax.servlet.ServletOutputStream
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * Created by kerry on 2016/10/25.
 * run jetty server providing mock data and add a meta to local database using h2 engine
 */

final String ENCODING = 'utf-8'

Map params = [:]
if (args) {
	for (it in args) {
		def arr = it.split('=')
		if (arr.size() == 2)
			params[arr[0]] = arr[1]
	}
}

HttpServletResponse.metaClass.json = { Object obj ->
    HttpServletResponse resp = (HttpServletResponse) delegate
    resp.setContentType("application/json;charset=" + ENCODING)

    String str = JSON.toJSONString(obj)
    byte[] bytes = str.getBytes(ENCODING)
    resp.setContentLength(bytes.length)

    ServletOutputStream os = resp.getOutputStream()
    os.write(bytes)
    os.flush()
    os.close()
}

HttpServletRequest.metaClass.bodyHandler = { Closure cl ->
    HttpServletRequest req = (HttpServletRequest) delegate

    ServletInputStream is = req.inputStream
    byte[] bytes = Utils.readBytes(is)

    String body
    if (bytes.length == 0)
        body = req.getParameterNames().nextElement().toString()
    else
        body = new String(bytes, ENCODING)

    cl.call(body)
}

Logger log = LoggerFactory.getLogger(this.getClass())

CompilerConfiguration compileConf = new CompilerConfiguration()
compileConf.sourceEncoding = ENCODING
String classpath = 'handler'
compileConf.classpath = classpath

Binding binding = new Binding()
binding.setProperty('handler', Handler.inst)
final GroovyShell shell = new GroovyShell(GroovyCl.gcl, binding, compileConf)

Timer timer = new Timer()
TimerTask task = new TimerTask() {
    Map<String, Long> modified = new HashMap<String, Long>()

    private void evalFile(File f) {
        if (f.isDirectory()) {
            for (File sub : f.listFiles()) {
                evalFile(sub)
            }
        } else if (f.isFile() && f.getName().endsWith(".groovy")) {
            String path = f.absolutePath
            Long t = modified.get(path)
            if (t == null || t.longValue() != f.lastModified()) {
                modified[path] = f.lastModified()
                try {
                    shell.evaluate(f)
                    log.info('eval done 4 ' + f.name)
                } catch (Exception e) {
                    log.error('eval router error', e)
                }
            }
        }
    }

    @Override
    public void run() {
        File d = new File(classpath)
        if (!d.exists())
            return
        evalFile(d)
    }
}
timer.schedule(task, new Date(), 10 * 1000)

def s = new Server(params.port ? params.port as int : 8899)
s.setHandler(new AbstractHandler() {
    @Override
    void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        Handler.inst.route(request, response)
    }
})

Thread.start {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
    while (true) {
        String line = br.readLine()
        if (line == 'quit') {
            log.info('server stopped')
            s.stop()
            break
        }
    }
    System.exit(1)
}

log.info('server starting...')
s.setDumpAfterStart(false)
s.setDumpBeforeStop(false)
s.start()
s.join()